package agent

import (
	"fmt"
	"openmanus/llm/history"

	"github.com/axcom/ninego/class"
)

// ReActAgent interface defines the methods that must be implemented
type IReActAgent interface {
	Think() (bool, error)  //处理当前状态并决定下一步行动
	Act() (string, error)  //执行决定的行动
	Step() (string, error) //执行单个步骤（实现了BaseAgent的抽象方法）
}

// 实现思考-行动循环模式
type ReActAgent struct {
	BaseAgent
}

// NewBaseAgent is a constructor for BaseAgent
func NewReactAgent(name string, llm *LLMClient) *ReActAgent {
	return &ReActAgent{
		BaseAgent: BaseAgent{
			Name:        name,
			LLM:         llm,
			Memory:      &history.Memory{},
			State:       IDLE,
			MaxSteps:    10,
			CurrentStep: 0,
		},
	}
}

// Think 思考并决定下一步动作（需要子类实现）
func (a *ReActAgent) Think() (bool, error) {
	ret, handled := a.Inherited()
	if handled {
		return class.SC[bool](ret[0]), class.SC[error](ret[1])
	}

	// Implementation goes here
	fmt.Println("Think...")
	return false, fmt.Errorf("Think方法需要在子类中实现")
}

// Act 执行决定的动作（需要子类实现）
func (a *ReActAgent) Act() (string, error) {
	ret, handled := a.Inherited()
	if handled {
		return class.SC[string](ret[0]), class.SC[error](ret[1])
	}

	// Implementation goes here
	return "", fmt.Errorf("Act方法需要在子类中实现")
}

// Step executes a single step: think and act
// 实现了思考-行动循环
func (a *ReActAgent) Step() (string, error) {
	ret, handled := a.Inherited()
	if handled {
		return class.SC[string](ret[0]), class.SC[error](ret[1])
	}

	a.mu.Lock()
	defer a.mu.Unlock()
	fmt.Println("Step...")

	//执行单个步骤：思考和行动。
	shouldAct, err := a.Think() //先思考
	if err != nil {
		return "", fmt.Errorf("思考失败: %w", err)
	}
	if !shouldAct {
		//思考完成 - 无需行动
		a.State = FINISHED
		return "思考完成 - 不需要行动", nil
	}
	return a.Act() //再行动
}
